/**
 * Created by TWC
 * on 2021/05/30
 * <p>
 * Company :thundersoft
 */
package com.twc0329.mycamera.Activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Size;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Chronometer;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.view.MotionEventCompat;

import com.twc0329.mycamera.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;


public class MainActivity extends AppCompatActivity {

    private              int[]                faceDetectModes;
    private              TextureView          textureView;
    private              CameraManager        cameraManager;
    private              CameraDevice         cameraDevice;
    private              Surface              textureViewSurface;
    private              Surface              imageReaderSurface,imageReaderSurfaceVideo;
    private              CameraCaptureSession cameraCaptureSession;
    private              CameraCaptureSession previewSession;
    private              ImageButton          btnPhoto, takpho1, videopause;
    private ImageReader imageReader,imageReaderVideo;
    private ImageView   imageView, imageRecord,imageVideo;
    private MediaRecorder recorder;
    private View          mFlashLayout, mwb, mFlashCheck;
    private CaptureRequest.Builder previewBuilder;
    private ImageButton            check;
    private CameraCharacteristics  cameraCharacteristics;
    private TextView               openLight, closeLight, awb, tv_flashStatus, tv_checkStatus, tkpho, checkrecord, timetkp, time3, time10, seconds, shotpho, wb, three, five, slowopne, slowclose, face, hihlight;
    private String                 mNextVideoAbsolutePath;
    private Size                   mVideoSize;
    private int                    lih       = 0;
    private CaptureRequest.Builder builder;
    private String                 mCameraID = "0";
    private ImageView              iv_flash;
    private ImageView              checkmodel, light, lamp, clouds, sun;
    private int     temp, videotemp = 0;
    private short          mDelayTime = 0;
    private Chronometer    time;
    private View           focus;
    private int            i          = 0;
    private Boolean        ifslow     = false;
    private MediaPlayer    music;
    private CountDownTimer countdowntime;
    private Face[]         faces;
    private Handler        mTimeHandler;
    private Size           mPreviewSize;
    private Size           mCaptureSize;
    private Boolean        isshoot    = false;
    private List<Address>  adress;
    private String         adressname;
    private long           mRecordTime;
    private Handler uiHandler;
    private int k = 0 ;



    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //隐藏标题栏
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        //隐藏状态栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        //初始化控件
        initView();
        //初始化显示图片
        getImage();
        requestPermissions(new String[]{
                Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION}, 1);

        mTimeHandler = new Handler() {
            public void handleMessage(Message msg) {
                if (faces == null) {
                    face.setText("0");
                } else {
                    face.setText("" + faces.length);
                }
                sendEmptyMessageDelayed(0, 1000);
            }
        };

        mTimeHandler.sendEmptyMessageDelayed(0, 1000);

        //闪光灯
        iv_flash.setOnClickListener(v -> {
            Animation anim = AnimationUtils.loadAnimation(this, R.anim.flash_in);
            mFlashLayout.setAnimation(anim);
            mFlashLayout.setVisibility(View.VISIBLE);
        });

        wb.setOnClickListener(v -> {
            Animation anim = AnimationUtils.loadAnimation(this, R.anim.flash_it);
            mwb.setAnimation(anim);
            mwb.setVisibility(View.VISIBLE);
            three.setVisibility(View.GONE);
            five.setVisibility(View.GONE);
            imageRecord.setVisibility(View.GONE);
            time.setVisibility(View.GONE);
            time3.setVisibility(View.GONE);
            time10.setVisibility(View.GONE);
            iv_flash.setVisibility(View.VISIBLE);
            tv_checkStatus.setText("白平衡");
            temp = 0;
            Animation animout = AnimationUtils.loadAnimation(this, R.anim.flash_out);
            mFlashCheck.setAnimation(animout);
            mFlashCheck.setVisibility(View.GONE);
        });


        //切换模式
        checkmodel.setOnClickListener(v -> {
            tv_checkStatus.setText("");
            slowopne.setVisibility(View.GONE);
            slowclose.setVisibility(View.GONE);
            three.setVisibility(View.GONE);
            five.setVisibility(View.GONE);
            time3.setVisibility(View.GONE);
            time10.setVisibility(View.GONE);
            Animation anim = AnimationUtils.loadAnimation(this, R.anim.flash_in);
            mFlashCheck.setAnimation(anim);
            mFlashCheck.setVisibility(View.VISIBLE);
        });

        //白平衡白炽灯
        light.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                k = 1;
                builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_INCANDESCENT);
                try {
                    cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                closeFlashLayout();
            }
        });

        //白平衡荧光灯模式
        lamp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                k = 2;
                builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_WARM_FLUORESCENT);
                try {
                    cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                closeFlashLayout();
            }
        });

        //白平衡多云模式
        clouds.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                k = 3 ;
                builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
                try {
                    cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                closeFlashLayout();
            }
        });


        //自动白平衡
        awb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                k = 4 ;
                builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_TWILIGHT);
                try {
                    cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                closeFlashLayout();
            }
        });

        //白平衡日光模式
        sun.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                k = 5 ;
                builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_FLUORESCENT);
                try {
                    cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                closeFlashLayout();
            }
        });

        //拍照button
        btnPhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (temp) {
                    //拍照模式
                    case 0:
                        if (lih == 100) {
                            builder.set(CaptureRequest.FLASH_MODE,
                                    CaptureRequest.FLASH_MODE_TORCH);
                            builder.addTarget(textureViewSurface);
                            try {
                                cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }
                        takePhoto();
                        break;
                    //录制视频模式
                    case 1:
                        videopause.setVisibility(View.VISIBLE);
                        takpho1.setVisibility(View.VISIBLE);
                        btnPhoto.setImageResource(R.drawable.recording);
                        //从什么时间开始
                        time.setBase(SystemClock.elapsedRealtime());
                        time.setFormat(":%s");
                        imageRecord.setVisibility(View.VISIBLE);
                        time.setVisibility(View.VISIBLE);
                        Toast.makeText(MainActivity.this, "开启录制", Toast.LENGTH_SHORT).show();
                        recorder();
                        PlayMusic(R.raw.recorder);
                        time.start();
                        temp = 2;
                        break;
                    //停止录制
                    case 2:
                        if (recorder != null) {
                            videopause.setVisibility(View.GONE);
                            takpho1.setVisibility(View.GONE);
                            btnPhoto.setImageResource(R.drawable.record);
                            time.stop();
                            imageRecord.setVisibility(View.GONE);
                            time.setVisibility(View.GONE);
                            Toast.makeText(MainActivity.this, "录制完成", Toast.LENGTH_SHORT).show();
                            recorder.stop();
                            recorder.release();
                            PlayMusic(R.raw.stoprecorder);
                            addVideo(MainActivity.this);
                            temp = 1;
                            MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                            mmr.setDataSource(mNextVideoAbsolutePath);
                            Bitmap bitmap2 = mmr.getFrameAtTime();
                            imageView.setImageBitmap(bitmap2);
                            try {
                                update();
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }

                        }
                        break;
                    //延时摄影模式
                    case 3:
                        countdowntime = new CountDownTimer(mDelayTime, 1000) {
                            @Override
                            public void onTick(long millisUntilFinished) {
                                seconds.setVisibility(View.VISIBLE);
                                seconds.setText("" + millisUntilFinished / 1000);
                                temp = 5;
                                if (millisUntilFinished / 1000 == 0) {
                                    seconds.setVisibility(View.GONE);
                                    takePhoto();
                                    temp = 3;
                                }
                            }

                            @Override
                            public void onFinish() {

                            }
                        }.start();
                        break;
                    //连续拍照
                    case 4:
                        try {

                            if (mCameraID.equals("1")) {
                                isshoot = true;
                            }
                            if (i == 3) {
                                shootpho();
                                PlayMusic(R.raw.takephosound);
                                i = 3;
                            } else {
                                shootpho();
                                PlayMusic(R.raw.takephosound);
                                i = 5;
                            }
                        } catch (CameraAccessException | IOException e) {
                            e.printStackTrace();
                        }
                        break;
                    //延时摄影中途直接拍照
                    case 5:
                        temp = 3;
                        countdowntime.cancel();
                        seconds.setVisibility(View.GONE);
                        takePhoto();
                        break;
                }

            }
        });

        //连拍
        shotpho.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                iv_flash.setVisibility(View.VISIBLE);
                time.setVisibility(View.GONE);
                tv_checkStatus.setText("连拍");
                temp = 4;
                closeFlashLayout();
                three.setVisibility(View.VISIBLE);
                five.setVisibility(View.VISIBLE);
                btnPhoto.setImageResource(R.drawable.takephoto);
                btnPhoto.setBackgroundResource(R.drawable.takephoto);
            }
        });

        //录制视频的时候暂停
        videopause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (videotemp) {
                    case 0:
                        recorder.pause();
                        time.stop();
                        mRecordTime = SystemClock.elapsedRealtime();
                        videopause.setImageResource(R.drawable.viodotake);
                        videotemp = 1;
                        break;
                    case 1:
                        time.setBase(time.getBase() + (SystemClock.elapsedRealtime() - mRecordTime));
                        time.start();
                        recorder.resume();
                        videopause.setImageResource(R.drawable.videopause);
                        videotemp = 0;
                }
            }
        });

        //录像中途点击拍照
        takpho1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    CaptureRequest.Builder builder1 = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                    builder1.addTarget(imageReaderSurfaceVideo);
                    previewSession.capture(builder1.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                imageVideo.setVisibility(View.VISIBLE);
                imageReaderVideo.setOnImageAvailableListener(reader -> {
                    Image image = reader.acquireNextImage();
                    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                    byte[] bytes = new byte[buffer.remaining()];
                    buffer.get(bytes);
                    image.close();
                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                    bitmap = photoRotation1(bitmap, 90);
                    if (isshoot) {
                        bitmap = photoRotation(bitmap, 180);
                    }
                    if (mCameraID.equals("1")) {
                        //前置摄像头拍的要先旋转180度
                        bitmap = photoRotation(bitmap, 180);
                    }
                    imageVideo.setImageBitmap(bitmap);
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            uiHandler.sendEmptyMessage(0);
                        }
                    });
                    thread.start();
                    try {
                        addPicture(MainActivity.this, bitmap);
                    } catch (IOException | CameraAccessException e) {
                        e.printStackTrace();
                    }
                }, null);
            }
        });

        //更新UI
        uiHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                if (msg.what == 0) {
                    imageVideo.setVisibility(View.GONE);
                } else {
                    Toast.makeText(MainActivity.this, "失败",
                            Toast.LENGTH_SHORT).show();
                }

            }

        };

        //点击选择三连拍模式
        three.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "选择三连拍", Toast.LENGTH_SHORT).show();
                i = 3;
                three.setVisibility(View.GONE);
                five.setVisibility(View.GONE);
            }
        });

        //点击选择五连拍模式
        five.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "选择五连拍", Toast.LENGTH_SHORT).show();
                i = 5;
                three.setVisibility(View.GONE);
                five.setVisibility(View.GONE);
            }
        });

        //选择闪光灯打开模式
        openLight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                lih = 100;
                closeFlashLayout();
                tv_flashStatus.setText("打开");
            }
        });

        //选择闪光灯关闭模式
        closeLight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                lih = 0;
                tv_flashStatus.setText("关闭");
                closeFlashLayout();
                closeLight();
            }
        });

        //选择闪光灯长亮模式
        hihlight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv_flashStatus.setText("长亮");
                closeFlashLayout();
                builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
                try {
                    cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        });

        tkpho.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                three.setVisibility(View.GONE);
                five.setVisibility(View.GONE);
                imageRecord.setVisibility(View.GONE);
                time.setVisibility(View.GONE);
                time3.setVisibility(View.GONE);
                time10.setVisibility(View.GONE);
                iv_flash.setVisibility(View.VISIBLE);
                tv_flashStatus.setText("关闭");
                tv_checkStatus.setText("拍照");
                temp = 0;
                closeFlashLayout();
                btnPhoto.setImageResource(R.drawable.takephoto);
                btnPhoto.setBackgroundResource(R.drawable.takephoto);
            }
        });

        checkrecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                three.setVisibility(View.GONE);
                five.setVisibility(View.GONE);
                time3.setVisibility(View.GONE);
                time10.setVisibility(View.GONE);
                iv_flash.setVisibility(View.GONE);
                tv_flashStatus.setText("");
                tv_checkStatus.setText("录像");
                temp = 1;
                btnPhoto.setImageResource(R.drawable.record);
                slowopne.setVisibility(View.VISIBLE);
                slowclose.setVisibility(View.VISIBLE);
                closeFlashLayout();
            }
        });

        timetkp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                three.setVisibility(View.GONE);
                five.setVisibility(View.GONE);
                iv_flash.setVisibility(View.VISIBLE);
                tv_flashStatus.setText("关闭");
                btnPhoto.setImageResource(R.drawable.takephoto);
                btnPhoto.setBackgroundResource(R.drawable.takephoto);
                imageRecord.setVisibility(View.GONE);
                time.setVisibility(View.GONE);
                tv_checkStatus.setText("延时摄影");
                temp = 3;
                time3.setVisibility(View.VISIBLE);
                time10.setVisibility(View.VISIBLE);
                closeFlashLayout();
                btnPhoto.setImageResource(R.drawable.takephoto);
                btnPhoto.setBackgroundResource(R.drawable.takephoto);
            }
        });

        time3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDelayTime = 3 * 1000 + 60;
                Toast.makeText(MainActivity.this, "选择3秒延时，选择成功", Toast.LENGTH_SHORT).show();
                time3.setVisibility(View.GONE);
                time10.setVisibility(View.GONE);
            }
        });

        time10.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDelayTime = 5 * 1000 + 60;
                Toast.makeText(MainActivity.this, "选择5秒延时，选择成功", Toast.LENGTH_SHORT).show();
                time3.setVisibility(View.GONE);
                time10.setVisibility(View.GONE);
            }
        });

        check.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    switchCamera();
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        });

        slowopne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "开启慢动作", Toast.LENGTH_SHORT).show();
                slowopne.setVisibility(View.GONE);
                slowclose.setVisibility(View.GONE);
                ifslow = true;
            }
        });

        slowclose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "关闭慢动作", Toast.LENGTH_SHORT).show();
                slowopne.setVisibility(View.GONE);
                slowclose.setVisibility(View.GONE);
                ifslow = false;
            }
        });

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(
                        Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivity(i);
            }
        });


        //预览画面触摸效果
        textureView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int fingerX, fingerY;
                int length = (int) (getResources().getDisplayMetrics().density * 80);
                switch (MotionEventCompat.getActionMasked(event)) {
                    case MotionEvent.ACTION_DOWN:
                        fingerX = (int) event.getX();
                        fingerY = (int) event.getY();
                        focus.setX(fingerX - length / 2);
                        focus.setY(fingerY - length / 2);
                        focus.setVisibility(View.VISIBLE);
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    while (true) {
                                        Thread.sleep(1000);
                                        focus.setVisibility(View.GONE);
                                        MeteringRectangle focusArea = new MeteringRectangle(fingerX - 100, fingerY - 100, 200, 200, MeteringRectangle.METERING_WEIGHT_DONT_CARE);
                                        builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
                                        builder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
                                        builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
                                        builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
                                        cameraCaptureSession.capture(builder.build(),null,null);
                                    }
                                } catch (Exception e) {
                                }
                            }
                        }).start();
                        break;
                }
                return false;
            }
        });


        //预览尺寸
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
                try {
                    cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraManager.getCameraIdList()[0]);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                //设置imageReader
                mCaptureSize = Collections.max(Arrays.asList(map.getOutputSizes(ImageReader.class)), new Comparator<Size>() {
                    @Override
                    public int compare(Size lhs, Size rhs) {
                        return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getHeight() * rhs.getWidth());
                    }
                });
                mPreviewSize = getMatchingSize2();
                imageReader = ImageReader.newInstance(mCaptureSize.getWidth(), mCaptureSize.getHeight(), ImageFormat.JPEG, 2);
                imageReaderSurface = imageReader.getSurface();
                textureViewSurface = new Surface(surface);
                try {
                    open();
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

            }

        });
    }


    //切换后重新打开继续预览
    @Override
    protected void onRestart() {
        super.onRestart();
        try {
            open();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    //启动音效
    private void PlayMusic(int MusicId) {
        music = MediaPlayer.create(this, MusicId);
        music.start();
    }

    //初始化绑定控件
    private void initView() {
        videopause = findViewById(R.id.videopause);
        takpho1 = findViewById(R.id.takpho1);
        awb = findViewById(R.id.awb);
        lamp = findViewById(R.id.lamp);
        sun = findViewById(R.id.sun);
        clouds = findViewById(R.id.clouds);
        light = findViewById(R.id.light);
        focus = findViewById(R.id.focus);
        tv_flashStatus = findViewById(R.id.tv_flash_status);
        tv_checkStatus = findViewById(R.id.tv_check_status);
        textureView = findViewById(R.id.textureView);
        btnPhoto = findViewById(R.id.button);
        imageView = findViewById(R.id.imageView);
        iv_flash = findViewById(R.id.iv_flash);
        checkmodel = findViewById(R.id.checkmodel);
        check = findViewById(R.id.check);
        time = findViewById(R.id.time);
        face = findViewById(R.id.face);
        imageRecord = findViewById(R.id.imagerecord);
        imageVideo = findViewById(R.id.imageVideo);
        time3 = findViewById(R.id.time3);
        time10 = findViewById(R.id.time10);
        mFlashLayout = findViewById(R.id.layout_flash_text);
        mwb = findViewById(R.id.laout_wb_text);
        mFlashCheck = findViewById(R.id.layout_check_text);
        hihlight = mFlashLayout.findViewById(R.id.hihlight);
        openLight = mFlashLayout.findViewById(R.id.open);
        closeLight = mFlashLayout.findViewById(R.id.close);
        tkpho = mFlashCheck.findViewById(R.id.tkpho);
        shotpho = mFlashCheck.findViewById(R.id.shotpho);
        wb = mFlashCheck.findViewById(R.id.wb);
        three = findViewById(R.id.three);
        five = findViewById(R.id.five);
        slowopne = findViewById(R.id.slowopen);
        slowclose = findViewById(R.id.slowclose);
        checkrecord = mFlashCheck.findViewById(R.id.checkrecord);
        timetkp = mFlashCheck.findViewById(R.id.timetkp);
        seconds = findViewById(R.id.seconds);
    }

    //初始化显示图片
    private void getImage() {
        Uri imagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;//获取照片地址uri
        ContentResolver content = this.getContentResolver();
        Bitmap bitmap = null;
        Cursor cursor = content.query(imagesUri, null //数据库查询
                , MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?"
                , new String[]{"image/jpeg", "image/png"}
                , MediaStore.Images.Media.DATE_MODIFIED);
        String path = null;
        while (cursor.moveToNext()) {
            path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        }
        cursor.close();
        bitmap = BitmapFactory.decodeFile(path);
        imageView.setImageBitmap(bitmap);
    }


    //预览回调开启预览
    CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            cameraCaptureSession = session;
            try {
                builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                builder.addTarget(textureViewSurface);
                // 自动对焦
                builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                builder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, getFaceDetectMode());//设置人脸检测级
                switch (k){
                    case 1:
                        builder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_INCANDESCENT);
                        break;
                    case 2:
                        builder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_WARM_FLUORESCENT);
                        break;
                    case 3:
                        builder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
                        break;
                    case 4:
                        builder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_TWILIGHT);
                        break;
                    case 5:
                        builder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_FLUORESCENT);
                        break;
                }
                cameraCaptureSession.setRepeatingRequest(builder.build(), new CameraCaptureSession.CaptureCallback() {

                    @Override
                    public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                        super.onCaptureCompleted(session, request, result);
                        faces = result.get(CaptureResult.STATISTICS_FACES);

                    }
                }, null);

            } catch (CameraAccessException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {

        }
    };

    //检查权限
    public boolean checkSelfPermissions() {
        if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
            return true;
        else
            return false;
    }

    //打开摄像头
    @SuppressLint("MissingPermission")
    public void open() throws CameraAccessException {
        faceDetectModes = cameraCharacteristics.get(CameraCharacteristics
                .STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);//支持的人脸检测模式
        StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        mVideoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder.class));
        imageReader.setOnImageAvailableListener(reader -> {
            Image image = reader.acquireNextImage();
            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            image.close();
            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            if (isshoot) {
                bitmap = photoRotation(bitmap, 180);
            }
            if (mCameraID.equals("1")) {
                //前置摄像头拍的要先旋转180度
                bitmap = photoRotation(bitmap, 180);
            }
            imageView.setImageBitmap(bitmap);
            try {
                addPicture(MainActivity.this, bitmap);
            } catch (IOException | CameraAccessException e) {
                e.printStackTrace();
            }
        }, null);

        //打开相机
        if (checkSelfPermissions()) {
            cameraManager.openCamera(mCameraID, new CameraDevice.StateCallback() {
                @Override
                public void onOpened(@NonNull CameraDevice camera) {
                    cameraDevice = camera;
                    try {
                        cameraDevice.createCaptureSession(Arrays.asList(textureViewSurface, imageReaderSurface), sessionStateCallback, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onDisconnected(@NonNull CameraDevice camera) {

                }

                @Override
                public void onError(@NonNull CameraDevice camera, int error) {

                }
            }, null);
        }
    }

    //连拍功能
    public void shootpho() throws CameraAccessException, IOException {
        CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
        if (lih == 100) {
            builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
        }
        // 根据设备方向计算设置照片的方向
        int result;
        if (mCameraID.equals("0")) {
            result = 90;
        } else {  // back-facing
            result = 270;
        }
        builder.set(CaptureRequest.JPEG_ORIENTATION, result);
        builder.addTarget(imageReader.getSurface());
        CaptureRequest request = builder.build();
        List<CaptureRequest> requestList = new ArrayList<>();
        while (i > 0) {
            requestList.add(request);
            i--;
        }
        cameraCaptureSession.captureBurst(requestList, null, null);
        Toast.makeText(MainActivity.this, "连拍完成", Toast.LENGTH_SHORT).show();
    }
    //设置检查人脸
    private int getFaceDetectMode() {
        if (faceDetectModes == null) {
            return CaptureRequest.STATISTICS_FACE_DETECT_MODE_FULL;
        } else {
            return faceDetectModes[faceDetectModes.length - 1];
        }
    }

    //预览大小
    private Size getMatchingSize2() {
        Size selectSize = null;
        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraManager.getCameraIdList()[0]);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        Size[] sizes = streamConfigurationMap.getOutputSizes(ImageFormat.JPEG);
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int deviceWidth = displayMetrics.widthPixels; //屏幕分辨率宽
        int deviceHeigh = displayMetrics.heightPixels; //屏幕分辨率高

        //选择最佳比
        for (int j = 1; j < 41; j++) {
            for (int i = 0; i < sizes.length; i++) { //遍历所有Size
                Size itemSize = sizes[i];
                //判断当前Size高度小于屏幕宽度+j*5  &&  判断当前Size高度大于屏幕宽度-j*5
                if (itemSize.getHeight() < (deviceWidth + j * 5) && itemSize.getHeight() > (deviceWidth - j * 5)) {
                    if (selectSize != null) { //如果之前已经找到一个匹配的宽度
                        if (Math.abs(deviceHeigh - itemSize.getWidth()) > Math.abs(deviceHeigh - selectSize.getWidth())) { //求绝对值算出最接近设备高度的尺寸
                            selectSize = itemSize;
                            continue;
                        }
                    } else {
                        selectSize = itemSize;
                    }

                }
            }
            if (selectSize != null) {
                return selectSize;
            }
        }
        return selectSize;
    }

    //拍照
    private void takePhoto() {
        try {
            CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            builder.addTarget(imageReaderSurface);
            builder.set(CaptureRequest.JPEG_ORIENTATION, 90);
            //锁定af
            builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            //锁定AE，AWB
            builder.set(CaptureRequest.CONTROL_AE_LOCK, true);
            builder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
            PlayMusic(R.raw.takephosound);
            cameraCaptureSession.capture(builder.build(), new CameraCaptureSession.CaptureCallback() {

                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    try {
                        update();
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }
            }, null);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    //旋转图片
    Bitmap photoRotation(Bitmap bm, final int orientationDegree) {
        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
        m.postScale(-1, 1); // 镜像水平翻转
        try {
            Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
            return bm1;
        } catch (OutOfMemoryError ignored) {
        }
        return null;
    }

    //旋转图片
    Bitmap photoRotation1(Bitmap bm, final int orientationDegree) {
        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
        try {
            Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
            return bm1;
        } catch (OutOfMemoryError ignored) {
        }
        return null;
    }
    //关闭闪光灯
    public void closeLight() {
        builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
        try {
            cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    //切换摄像头
    public void switchCamera() throws CameraAccessException {
        if (mCameraID.equals("0")) {
            mCameraID = "1";
            iv_flash.setVisibility(View.GONE);
            tv_flashStatus.setText("");
            cameraDevice.close();
            open();
        } else {
            iv_flash.setVisibility(View.VISIBLE);
            tv_flashStatus.setText("关闭");
            mCameraID = "0";
            cameraDevice.close();
            open();
        }
    }

    //录像
    public void recorder() {
        try {
            prepareRecorder();
            previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
            previewBuilder.addTarget(recorder.getSurface());
            previewBuilder.addTarget(textureViewSurface);
            imageReaderVideo = ImageReader.newInstance(1920, 1080, ImageFormat.JPEG, 2);
            imageReaderSurfaceVideo = imageReaderVideo.getSurface();
            cameraDevice.createCaptureSession(Arrays.asList(recorder.getSurface(), textureViewSurface, imageReaderSurfaceVideo), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    previewSession = session;
                    updatePreview();
                    recorder.start();
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                }
            }, null);


        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    //更新录像预览
    private void updatePreview() {
        switch (k){
            case 1:
                previewBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_INCANDESCENT);
                break;
            case 2:
                previewBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_WARM_FLUORESCENT);
                break;
            case 3:
                previewBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
                break;
            case 4:
                previewBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_TWILIGHT);
                break;
            case 5:
                previewBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_FLUORESCENT);
                break;
        }
        try {
            previewSession.setRepeatingRequest(previewBuilder.build(), null, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    //更新拍照预览
    private void update() throws CameraAccessException {
        cameraDevice.createCaptureSession(Arrays.asList(textureViewSurface, imageReaderSurface), sessionStateCallback, null);

    }

    private void prepareRecorder() {
        recorder = new MediaRecorder();
        //设置其它必要参数
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
            mNextVideoAbsolutePath = getVideoFilePath(this);
        }
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        recorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
        if (ifslow) {
            recorder.setCaptureRate(120);
        }
        recorder.setVideoFrameRate(30);
        recorder.setOutputFile(mNextVideoAbsolutePath);
        recorder.setVideoEncodingBitRate(10000000);
        if (mCameraID.equals("0")) {
            recorder.setOrientationHint(90);
        } else
            recorder.setOrientationHint(270);
        //参数设置完毕后，调用prepare函数
        try {
            recorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private String getVideoFilePath(Context context) {
        //获取路径函数
        final File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        //卸载应用，删除存储的文件
        String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date());
        File image = null;
        try {
            image = File.createTempFile(
                    "JPEG_" + timeStamp,
                    ".mp4",
                    dir
            );

        } catch (IOException e) {
            e.printStackTrace();
        }
        return image == null ? "" : image.getAbsolutePath();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (checkSelfPermissions()) {
            try {
                open();
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }
        if (requestCode == 1) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    getlocation();
                } else {
                    Toast.makeText(this, "请在设置中更改定位权限", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    //获取地理位置信息
    private void getlocation() {
        LocationManager locationManager = (LocationManager) MainActivity.this.getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(false);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        String providerName = "";
        List<String> providerList = locationManager.getProviders(true);
        if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {
            providerName = LocationManager.NETWORK_PROVIDER;
        } else if (providerList.contains(LocationManager.GPS_PROVIDER)) {
            providerName = LocationManager.GPS_PROVIDER;
        } else {
            return;
        }

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        Location location = locationManager.getLastKnownLocation(providerName);
        if (location != null) {
            final double longitude = location.getLongitude();// 经度
            final double latitude = location.getLatitude();// 纬度
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    try {
                        Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
                        adress = geocoder.getFromLocation(latitude, longitude, 1);
                        adressname = adress.get(0).getAddressLine(0);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        } else {
            Toast.makeText(MainActivity.this, "定位失败", Toast.LENGTH_SHORT).show();
        }
    }


    //录像大小
    private static Size chooseVideoSize(Size[] choices) {
        for (Size size : choices) {
            if (size.getWidth() == size.getHeight() * 4 / 3 && size.getWidth() <= 1080) {
                return size;
            }
        }
        return choices[choices.length - 1];

    }


    //存储图片
    private void addPicture(Context context, Bitmap bmp) throws IOException, CameraAccessException {
        File appDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = "";
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            fileName = System.currentTimeMillis() + ".jpg";
        } else
            fileName = adressname + System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        FileOutputStream fos = new FileOutputStream(file);
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
        MediaScannerConnection connection = new MediaScannerConnection(context, null);
        connection.connect();
        MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, new String[]{"image/jpeg"}, null);
    }



    //存储视频
    private void addVideo(Context context) {
        MediaScannerConnection connection = new MediaScannerConnection(context, null);
        connection.connect();
        MediaScannerConnection.scanFile(context, new String[]{mNextVideoAbsolutePath}, new String[]{"video/mp4"}, null);
    }

    //返回动画
    public void closeFlashLayout() {
        Animation anim = AnimationUtils.loadAnimation(this, R.anim.flash_out);
        mFlashLayout.setAnimation(anim);
        mFlashLayout.setVisibility(View.GONE);
        mFlashCheck.setAnimation(anim);
        mFlashCheck.setVisibility(View.GONE);
        mwb.setAnimation(anim);
        mwb.setVisibility(View.GONE);
    }
}